package org.gpp.proj1.communication.manager;

import java.rmi.RemoteException;

import org.gpp.proj1.communication.CommunicationException;
import org.gpp.proj1.communication.ConnectionException;
import org.gpp.proj1.communication.processor.test.RequestCounter;
import org.gpp.proj1.communication.protocol.Message;
import org.gpp.proj1.communication.protocol.ProtocolIdentifiers;

import junit.framework.TestCase;

public class RMINetworkManagerTest extends TestCase {

	private static final int TEST_PORT = 1100;

	public void testBroadcastMessage() throws RemoteException, CommunicationException, ConnectionException {
		RMINetworkManager manager1 = new RMINetworkManager( TEST_PORT );
		RMINetworkManager manager2 = new RMINetworkManager( TEST_PORT + 1 );

		// There's no need to manager2 connect to manager1! The connection
		// already is two-way!
		manager1.connectTo( "localhost", TEST_PORT + 1 );
		
		// Registering listeners
		RequestCounter counter1 = new RequestCounter();		
		manager1.registerRequestListener( counter1 );
		
		RequestCounter counter2 = new RequestCounter();		
		manager2.registerRequestListener( counter2 );
		
		// Sending messages
		manager2.broadcastMessage( new Message( ProtocolIdentifiers.CHAT, new String[]{ "Oh hai" } ) );
		
		assertEquals( 1, counter1.received.size() );
		assertEquals( ProtocolIdentifiers.CHAT, counter1.received.get(0).getIdentifier() );
		
		manager1.broadcastMessage( new Message( ProtocolIdentifiers.CHAT, new String[]{ "Yo dawg" } ) );
		
		assertEquals( 1, counter2.received.size() );
		assertEquals( ProtocolIdentifiers.CHAT, counter2.received.get(0).getIdentifier() );
		
		// Disconnecting manager2
		manager2.stop();
		
		// Message should not be sent, manager2 is offline!
		manager1.broadcastMessage( new Message( ProtocolIdentifiers.CHAT, new String[]{ "Yo dawg" } ) );
		
		assertEquals( 1, counter1.received.size() );
		assertEquals( ProtocolIdentifiers.CHAT, counter1.received.get(0).getIdentifier() );
		
		assertEquals( 1, counter2.received.size() );
		assertEquals( ProtocolIdentifiers.CHAT, counter2.received.get(0).getIdentifier() );
		
		// Disconnecting manager1
		manager1.stop();
	}
	
	public void testSendMessage() throws RemoteException, CommunicationException, ConnectionException {
		RMINetworkManager manager1 = new RMINetworkManager( TEST_PORT );
		RMINetworkManager manager2 = new RMINetworkManager( TEST_PORT + 1 );

		// There's no need to manager2 connect to manager1! The connection
		// already is two-way!
		String manager2Id = manager1.connectTo( "localhost", TEST_PORT + 1 );
		
		// Registering listeners
		RequestCounter counter1 = new RequestCounter();		
		manager1.registerRequestListener( counter1 );
		
		RequestCounter counter2 = new RequestCounter();		
		manager2.registerRequestListener( counter2 );
		
		// Sending messages
		manager2.broadcastMessage( new Message( ProtocolIdentifiers.CHAT, new String[]{ "Oh hai" } ) );
		
		assertEquals( 1, counter1.received.size() );
		assertEquals( ProtocolIdentifiers.CHAT, counter1.received.get(0).getIdentifier() );
		
		manager1.sendMessage( manager2Id, new Message( ProtocolIdentifiers.CHAT, new String[]{ "Yo dawg" } ) );
		
		assertEquals( 1, counter2.received.size() );
		assertEquals( ProtocolIdentifiers.CHAT, counter2.received.get(0).getIdentifier() );
		
		// Disconnecting manager2
		manager2.stop();
		
		// Message should not be sent, manager2 is offline!
		manager1.broadcastMessage( new Message( ProtocolIdentifiers.CHAT, new String[]{ "Yo dawg" } ) );
		
		assertEquals( 1, counter1.received.size() );
		assertEquals( ProtocolIdentifiers.CHAT, counter1.received.get(0).getIdentifier() );
		
		assertEquals( 1, counter2.received.size() );
		assertEquals( ProtocolIdentifiers.CHAT, counter2.received.get(0).getIdentifier() );
		
		// Disconnecting manager1
		manager1.stop();
	}
}
